﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Kernel;

namespace SppdProjectHelper
{
    public partial class Form_BaseMapLead: FormBase
    {
        public Form_BaseMapLead()
        {
            InitializeComponent();

            syncCtrl.CreateControl();
        }

        public Form_BaseMapLead( IControlPad pad )
            :base(pad)
        {
            InitializeComponent();

            syncCtrl.CreateControl();
        }

        public ProjectConfig ProjectConfig { set { _prj_cnf = value; } }

        protected BindingList<FileInfo> SrcFiles = new BindingList<FileInfo>();  //保存当前目录的所有文件
        protected BindingList<FileInfo> DstFiles = new BindingList<FileInfo>();  //保存要导入的文件

        public delegate void BackgroundProcessingDelegate();    //后台进程代理
        public delegate void BackgroundProcessingDelegateEx(FileInfo fileInfo, Database db, Transaction transaction, BlockTableRecord modelSpace);    //后台进程代理
        private System.Threading.SynchronizationContext _uiContext ;//调度线程的UI线程同步上下文
        private static Control syncCtrl = new Control();//用于同步的控件
        private ProjectConfig _prj_cnf=null;
        private static string _save_folder = "";
        private static bool _save_check_raw = true;
        private static bool _save_check_blk = false;
        private static bool _save_check_ref = false;

        protected virtual void Menu_Item_Click( object sender, EventArgs e)
        {
            //switch((sender as DevComponents.DotNetBar.ButtonItem).Text)
            //{
            //    case "关闭":
            //        this.Close();
            //        break;
            //    case "打印":
            //        previewControl_main.Print();
            //        break;
            //}
        }

        protected void UI_Init()
        {
            //初始化list
            funcDataGridViewInit(this.dataGridView_src);

            funcDataGridViewInit(this.dataGridView_dst);

        }

        private void funcDataGridViewInit( DataGridView dataGridView)
        {
            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView.AutoGenerateColumns = false;

            string[] v_names = { "Name", "Length", "FullName" };
            string[] v_headerTexts = { "名称", "大小", "路径" };
            int[] v_widths = { 96, 64, 320 };
            bool[] v_visables = { true, true, true, true };
            bool[] v_readOnlys = { true, true, true, true };

            int n = v_names.Length;
            for (int i = 0; i < n; i++)
            {
                DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
                dgvc.DataPropertyName = v_names[i];
                dgvc.HeaderText = v_headerTexts[i];
                dgvc.Width = v_widths[i];
                dgvc.Visible = v_visables[i];
                dgvc.ReadOnly = v_readOnlys[i];
                dgvc.CellTemplate = new DataGridViewTextBoxCell();
                dataGridView.Columns.Add(dgvc);
            }
        }

        private void button_Click(object sender, EventArgs e)
        {
            var ctl = sender as Button;

            switch (ctl.Name)
            {
                case "button_openFolder":
                    {
                        FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
                        //folderBrowserDialog.RootFolder = "";
                        var dr = folderBrowserDialog.ShowDialog();
                        if( dr == DialogResult.OK)
                        {
                            this.textBox_folderPath.Text = folderBrowserDialog.SelectedPath;

                            //读取目录下全部文件
                            DirectoryInfo di = new DirectoryInfo(this.textBox_folderPath.Text);
                            var files_src = di.GetFiles("*.dwg");//得到所有的dwg文件
                            this.dataGridView_src.DataSource = files_src;
                        }
                    }
                    break;
                case "button_add":
                    {
                        var rows = dataGridView_src.SelectedRows;
                        foreach(DataGridViewRow row in rows)
                        {
                            var fi = row.DataBoundItem as FileInfo;
                            //如果右边不存在，就添加
                            if( DstFiles.Contains(fi) == false )
                                DstFiles.Add(fi);
                        }
                    }
                    break;
                case "button_addAll":
                    {
                        var rows = dataGridView_src.Rows;
                        foreach (DataGridViewRow row in rows)
                        {
                            var fi = row.DataBoundItem as FileInfo;

                            //如果右边不存在，就添加
                            if (DstFiles.Contains(fi) == false)
                                DstFiles.Add(fi);
                        }
                    }
                    break;
                case "button_del":
                    {
                        var rows = dataGridView_dst.SelectedRows;
                        foreach (DataGridViewRow row in rows)
                        {
                            var fi = row.DataBoundItem as FileInfo;

                            DstFiles.Remove(fi);
                        }
                    }
                    break;
                case "button_delAll":
                    DstFiles.Clear();
                    break;
                case "button_submit":
                    {
                        //保存相关配置
                        _save_folder = this.textBox_folderPath.Text;
                        _save_check_raw = this.radioButton_raw.Checked;
                        _save_check_blk = this.radioButton_block.Checked;
                        _save_check_ref = this.radioButton_ref.Checked;

                        if (this.radioButton_raw.Checked == true)
                        {
                            //var thread = new Thread(funcDwgFileDeepCopyAsRaw);
                            //thread.Start();
                            syncCtrl.BeginInvoke(new BackgroundProcessingDelegate(funcDwgFileDeepCopyAsRaw));
                        }
                        else if (this.radioButton_block.Checked == true)
                        {
                            //Misc.Alert("功能暂未实现。");
                            //var thread = new Thread(funcDwgFileDeepCopyAsBlock);
                            //thread.Start();
                            syncCtrl.BeginInvoke(new BackgroundProcessingDelegate(funcDwgFileDeepCopyAsBlock));
                        }
                        else if (this.radioButton_ref.Checked == true)
                        {
                            //var thread = new Thread(funcDwgFileDeepCopyAsBlockRef);
                            //thread.Start();
                            syncCtrl.BeginInvoke(new BackgroundProcessingDelegate(funcDwgFileDeepCopyAsBlockRef));
                        }
                        else
                        {
                            Misc.Alert("未执行任何复制操作。");
                            funcUITransCompleted();
                        }
                        //this.Close();
                    }
                    break;
            }
            //更新计数
            funcUITransStatusUpdate(0);
        }

        /// <summary>
        /// 将列表中的cad文件的内容对应坐标拷到当前活动文档中(直接复制)
        /// </summary>
        private void funcDwgFileDeepCopyAsRaw()
        {
            //更新界面
            funcUITransing();
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            //Database db = doc.Database;
            //using (Transaction tr = db.TransactionManager.StartTransaction())
            //{
            //    int n_current = 0;
            //    foreach( var file_r in DstFiles)
            //    {//遍历所有需要被拷贝的文件
            //        //更新计数控件
            //        funcUITransStatusUpdate(++n_current);

            //        using (Database srcDb = new Database(false, false))
            //        {
            //            srcDb.ReadDwgFile( file_r.FullName, FileOpenMode.OpenForReadAndReadShare, true, "");
            //            ObjectIdCollection oids = Common.GetDbModelSpaceEntities(srcDb);//获取所有图元
            //            if (oids.Count > 0)
            //            {
            //                IdMapping idMap = new IdMapping();
            //                srcDb.WblockCloneObjects(oids, db.CurrentSpaceId, idMap, DuplicateRecordCloning.Ignore, false);//克隆图元
            //            }
            //        }
            //    }
            //    tr.Commit();
            //}
            int n_current = 0;
            foreach (var file_r in DstFiles)
            {
                funcUITransStatusUpdate(++n_current);
                Common.DwgFileClone(doc, file_r, Common.DwgFileCloneMode.Raw, "");
            }
            //更新界面
            funcUITransCompleted();
        }
        
        /// <summary>
        /// 将列表中的cad文件的内容对应坐标拷到当前活动文档中(按块复制)
        /// </summary>
        private void funcDwgFileDeepCopyAsBlock()
        {
            //更新界面
            funcUITransing();
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            //Database db = doc.Database;
            //using(Transaction trans = db.TransactionManager.StartTransaction()){
            //    BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
            //    BlockTableRecord blk = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;//得到模型空间的块表记录

            //    int n_current = 0;
            //    foreach ( var file_r in DstFiles)
            //    {//遍历所有需要被拷贝的文件
            //        //更新计数控件
            //        funcUITransStatusUpdate(++n_current);

            //        using (Database srcDb = new Database(false, false))
            //        {
            //            //将数据文件读入内存
            //            srcDb.ReadDwgFile(file_r.FullName, FileOpenMode.OpenForReadAndReadShare, true, "");
            //            //以块的形式将数据存入目标数据库
            //            ObjectId blockId = db.Insert(Guid.NewGuid().ToString(), srcDb, false);
            //            //创建当前块的一个块引用
            //            using (BlockReference br = new BlockReference(Point3d.Origin, blockId))
            //            {
            //                blk.AppendEntity(br);//将块引用添加到模型空间
            //                trans.AddNewlyCreatedDBObject(br, true);
            //            }
            //        }
            //    }

            //    trans.Commit();
            //}
            int n_current = 0;
            foreach (var file_r in DstFiles)
            {
                funcUITransStatusUpdate(++n_current);
                Common.DwgFileClone(doc, file_r, Common.DwgFileCloneMode.Block, Guid.NewGuid().ToString());
            }
            //更新界面
            funcUITransCompleted();
        }

        /// <summary>
        /// 将列表中的cad文件的内容对应坐标拷到当前活动文档中(按块引用复制)
        /// </summary>
        private void funcDwgFileDeepCopyAsBlockRef()
        {
            //更新界面
            funcUITransing();
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            //Database db = doc.Database;
            //using (Transaction trans = db.TransactionManager.StartTransaction())
            //{
            //    BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            //    BlockTableRecord modelSpace = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            //    int n_current = 0;
            //    foreach (var file_r in DstFiles)
            //    {//遍历所有需要被拷贝的文件
            //        //更新计数控件
            //        funcUITransStatusUpdate(++n_current);
            //        //using (Database srcDb = new Database(false, false))
            //        {
            //            ObjectId refid = db.OverlayXref(file_r.FullName, Guid.NewGuid().ToString());//把外部文件转换为块文件
            //            BlockReference br = new BlockReference(Point3d.Origin, refid);//通过块定义创建块参照
            //            modelSpace.AppendEntity(br);//把块参照添加到块表记录
            //            trans.AddNewlyCreatedDBObject(br, true);
            //        }
            //    }

            //    trans.Commit();
            //}
            int n_current = 0;
            foreach (var file_r in DstFiles)
            {
                funcUITransStatusUpdate(++n_current);
                Common.DwgFileClone(doc, file_r, Common.DwgFileCloneMode.BlockRef, Guid.NewGuid().ToString());
            }
            //更新界面
            funcUITransCompleted();
        }

        /// <summary>
        /// 此函数会试着打开上次使用的路径
        /// </summary>
        private void funcTryOpenLastFolder()
        {
            this.textBox_folderPath.Text = _save_folder;
            if (true == Directory.Exists(_save_folder))
            {
                //读取目录下全部文件
                DirectoryInfo di = new DirectoryInfo(this.textBox_folderPath.Text);
                var files_src = di.GetFiles("*.dwg");//得到所有的dwg文件
                this.dataGridView_src.DataSource = files_src;
            } 
        }

        /// <summary>
        /// 当前转换状态更新
        /// </summary>
        private void funcUITransStatusUpdate( int trans_count_current )
        {
            //label_transCountAll.Text = string.Format("当前选择：{0}项",DstFiles.Count);
            SysMisc.InvokeHelper.Set(this.label_transCountAll, "Text", string.Format("当前选择：{0}项", DstFiles.Count));
            //label_transCountCurrent.Text = string.Format("当前完成：{0}项", trans_count_current);
            SysMisc.InvokeHelper.Set(this.label_transCountCurrent, "Text", string.Format("当前完成：{0}项", trans_count_current));
        }
        /// <summary>
        /// 转换完成更新
        /// </summary>
        private void funcUITransing()
        {
            SysMisc.InvokeHelper.Set(this.button_submit, "Text", "正在导入");
            SysMisc.InvokeHelper.Set(this.button_submit, "Enabled", false);
            //this.button_submit.Text = "正在导入";
            //this.button_submit.Enabled = false;

            SysMisc.InvokeHelper.Set(this.button_openFolder, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.button_add, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.button_addAll, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.button_del, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.button_delAll, "Enabled", false);
            //this.button_openFolder.Enabled = false;
            //this.button_add.Enabled = false;
            //this.button_addAll.Enabled = false;
            //this.button_del.Enabled = false;
            //this.button_delAll.Enabled = false;

            SysMisc.InvokeHelper.Set(this.radioButton_raw, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.radioButton_block, "Enabled", false);
            SysMisc.InvokeHelper.Set(this.radioButton_ref, "Enabled", false);
            //this.radioButton_raw.Enabled = false;
            //this.radioButton_block.Enabled = false;
            //this.radioButton_ref.Enabled = false;
        }

        /// <summary>
        /// 转换完成更新
        /// </summary>
        private void funcUITransCompleted()
        {
            SysMisc.InvokeHelper.Set(this.button_submit, "Text", "开始导入");
            SysMisc.InvokeHelper.Set(this.button_submit, "Enabled", true);
            //this.button_submit.Text = "开始导入";
            //this.button_submit.Enabled = true;

            SysMisc.InvokeHelper.Set(this.button_openFolder, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.button_add, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.button_addAll, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.button_del, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.button_delAll, "Enabled", true);
            //this.button_openFolder.Enabled = true;
            //this.button_add.Enabled = true;
            //this.button_addAll.Enabled = true;
            //this.button_del.Enabled = true;
            //this.button_delAll.Enabled = true;

            SysMisc.InvokeHelper.Set(this.radioButton_raw, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.radioButton_block, "Enabled", true);
            SysMisc.InvokeHelper.Set(this.radioButton_ref, "Enabled", true);
            //this.radioButton_raw.Enabled = true;
            //this.radioButton_block.Enabled = true;
            //this.radioButton_ref.Enabled = true;

            Misc.Alert("导入成功，请关闭本软件，查看导入效果。");
            SysMisc.InvokeHelper.Invoke(this, "Close"); //退出当前界面
        }

        private void Form_BaseMapLead_Load(object sender, EventArgs e)
        {
            UI_Init();

            //初始化相关配置
            this.dataGridView_src.DataSource = SrcFiles;
            this.dataGridView_dst.DataSource = DstFiles;
            
            this.radioButton_raw.Checked = _save_check_raw;
            this.radioButton_block.Checked = _save_check_blk;
            this.radioButton_ref.Checked = _save_check_ref;

            //试着打开上次使用的路径
            funcTryOpenLastFolder();

            funcUITransStatusUpdate(0);
        }
    }
}
